package com.weilive.core.code.parsers;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.weilive.core.utils.FileUtils;

public class SqlFileParser {

	private final static String TABLE_START_PREFIX = "create table";
	private final static String TABLE_END_PREFIX = ")";
	private final static String FIELD_START_PREFIX = "`";

	private static final String AUTO_INCREMENT_KEY = "auto_increment";
	private static final String PRIMARY_KEY = "primary key";
	private static final String PLAYER_ID = "player_id";

	public static class Field {
		public String name;
		public String type;
		public String comment;
	}

	public static class Table {
		public String name;
		public boolean hasDate;
		public boolean hasVersion;
		public boolean hasPlayerId;
		public String autoKey;
		public List<String> primaryKeys = new ArrayList<String>();
		public List<Field> fields = new ArrayList<Field>();
		
		public String getJavaType(String key) {
			for (Field f : fields) {
				if (f.name.equals(key)) {
					return f.type;
				}
			}
			return null;
		}
	}

	public static class SqlFile {
		public String name;
		public List<Table> tables = new ArrayList<Table>();
	}

	private static String getName(String line) {
		int idx1 = line.indexOf('`');
		if (idx1 < 0)
			return null;
		int idx2 = line.indexOf('`', idx1 + 1);
		if (idx2 < idx1 + 1)
			return null;
		return line.substring(idx1 + 1, idx2);
	}

	private static void getPrimaryKey(String line, List<String> list) {
		while (line.indexOf('`') > 0) {
			int idx1 = line.indexOf('`');
			if (idx1 < 0)
				return;
			int idx2 = line.indexOf('`', idx1 + 1);
			if (idx2 < idx1 + 1)
				return;
			String key = line.substring(idx1 + 1, idx2);
			list.add(key);
			line = line.substring(idx2 + 1, line.length());
		}
	}

	private static String getJavaType(String line) {

		int idx1 = line.indexOf('`');
		if (idx1 < 0)
			return null;
		int idx2 = line.indexOf('`', idx1 + 1);
		if (idx2 < idx1 + 1)
			return null;
		String lowLine = line.substring(idx2 + 1, line.length()).toLowerCase();

		// String lowLine = line.toLowerCase();
		if (lowLine.contains("char") || lowLine.contains("text")) {
			return "String";
		} else if (lowLine.contains("bigint")) {
			return "long";
		} else if (lowLine.contains("tinyint") || lowLine.contains("smallint") || lowLine.contains("int")) {
			return "int";
		} else if (lowLine.contains("timestamp")) {
			return "Date";
		} else if (lowLine.contains("blob") || lowLine.contains("binary")) {
			return "byte[]";
		} else if (lowLine.contains("double") || lowLine.contains("decimail")) {
			return "double";
		} else if (lowLine.contains("float")) {
			return "float";
		}
		return null;
	}

	private static String getComment(String line) {
		int idx0 = line.toLowerCase().indexOf("comment");
		if (idx0 < 0)
			return null;
		int idx1 = line.indexOf('\'', idx0 + 1);
		if (idx1 < idx0 + 1)
			return null;
		int idx2 = line.indexOf('\'', idx1 + 1);
		if (idx2 < idx1 + 1)
			return null;
		return line.substring(idx1 + 1, idx2);
	}

	public static SqlFile parse(File file) throws Exception {
		SqlFile sqlFile = new SqlFile();
		sqlFile.name = file.getName();
		int pos = sqlFile.name.indexOf('.');
		if (pos > 0)
			sqlFile.name = sqlFile.name.substring(0, pos);

		BufferedReader reader = new BufferedReader(new FileReader(file));
		String line;
		while ((line = reader.readLine()) != null) {
			line = line.trim();
			if (line.toLowerCase().startsWith(TABLE_START_PREFIX)) {
				Table table = new Table();
				sqlFile.tables.add(table);
				table.name = getName(line);
				table.hasDate = false;

				while ((line = reader.readLine()) != null) {
					line = line.trim();
					if (line.toLowerCase().startsWith(TABLE_END_PREFIX)) {
						break;
					}
					if (table.autoKey == null && line.toLowerCase().contains(AUTO_INCREMENT_KEY)) {
						table.autoKey = getName(line);
					}
					if (line.toLowerCase().contains(PRIMARY_KEY)) {
						getPrimaryKey(line, table.primaryKeys);
					}
					if (line.toLowerCase().startsWith(FIELD_START_PREFIX)) {
						Field field = new Field();
						table.fields.add(field);
						field.name = getName(line);
						field.type = getJavaType(line);

						if (field.type == null) {
							System.out.println(line);
							System.out.println(field.name);
						}
						field.comment = getComment(line);
						if (field.name.equals("version")) {
							table.hasVersion = true;
						}
						if (field.name.equals(PLAYER_ID)) {
							table.hasPlayerId = true;
						}
						if (field.type.equals("Date"))
							table.hasDate = true;
					}
				}
			}
		}
		reader.close();
		return sqlFile;
	}

	public static void main(String[] args) throws Exception {
		String file = FileUtils.getTestResourceDir() + "database/mysql/platform/platform_user.sql";
		SqlFile sqlFile = parse(new File(file));
		System.out.println(JSONObject.toJSONString(sqlFile));
	}
}
